import { Component, forwardRef, Injector, Input } from '@angular/core'
import { NG_VALUE_ACCESSOR } from '@angular/forms'
import { Observable } from 'rxjs'

import { CountryService } from './country.service'
import { ICountryQueryParams, Country } from '@shared/interfaces/common'
import { AbstractCustomSelectComponent } from '../custom-select/custom-select.component'
import { IGenericPagination } from '@shared/interfaces/pagination'
import { objectArrayDeduplication } from 'app/utils/helpers'
import { take, map } from 'rxjs/operators'

const TYPE_STR = 'codeAlpha3'
@Component({
  selector: 'app-country-select',
  templateUrl: './country-select.component.html',
  styles: [],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => CountrySelectComponent),
      multi: true,
    },
  ],
})
export class CountrySelectComponent extends AbstractCustomSelectComponent<Country, ICountryQueryParams> {

  constructor(
    private countryService: CountryService,
    public injector: Injector
  ) {
    super(injector)
  }

  @Input() type: 'origin' | 'string' = 'origin' // 默认传对象回去, 可以指定传 string

  _params: ICountryQueryParams = {
    size: 10,
    page: 1,
  }

  deduplicate(list: Country[]): Country[] {
    return objectArrayDeduplication(list, TYPE_STR)
  }

  compareFn = (o1: Country | string, o2: Country | string) => {
    if (typeof o1 === 'string' && typeof o2 === 'string') {
      return o1 && o2 ? o1 === o2 : false
    }

    if (o1 && o2) {
      return (o1 as Country).codeAlpha3 === (o2 as Country).codeAlpha3
    }

    return o1 === o2
  }

  query(params: ICountryQueryParams): Observable<IGenericPagination<Country>> {
    return this.countryService.paging(params)
  }

  getParams(): ICountryQueryParams {
    return this._params
  }

  loadMore(): void {
    if (this.isLoading) {
      return
    }
    this.isLoading = true
    this._params.page++
    this.searchChange$.next(this.getParams())
  }

  onSearch(value: string): void {
    this.isLoading = true
    this._options = []
    this._params.page = 1
    this._params.keyword = value
    this.searchChange$.next(this.getParams())
  }

  writeValue(value: Country): void {
    this._value = value
    if (value) {
      /** value 为 string，当前只有在 Country 组件中使用，其他场景需要区别处理 */
      if (typeof value === 'string') {
        this.getInputOption(value)
      } else {
        this._options = [value, ...this._options]
        this.refreshRequest$.next('refresh')
      }
    }
    setTimeout(() => this.cdRef.detectChanges(), 0)
  }

  getInputOption(value: string) {
    const data = { codeAlpha3: value, name: value }
    this._params.keyword = value
    this.countryService.paging(this.getParams())
    .pipe(
      take(1),
      map(res => {
        this._params.keyword = null
        return Object.assign(data, res.data[0])
      })
    ).subscribe(res => {
      this._options = [res, ...this._options]
      this.refreshRequest$.next('refresh')
    })
    this._params.keyword = null
  }
}
